//
//  FlipView.m
//  MoKe
//
//  Created by hua zhang on 2/29/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "FlipView.h"
#import <QuartzCore/QuartzCore.h>

#define kFlipAnimationIntervalFast     0.2f
#define kFlipAnimationIntervalMedium   0.3f
#define kMoveThreshold                 0.05f

@interface FlipView ()

@property (nonatomic, retain) NSMutableArray *numberOfPagesArray;
@property (nonatomic, assign) UIView *currentView;
@property (nonatomic, assign) UIView *incomingView;

- (void)cleanupFlip;
@end

@implementation FlipView
@synthesize dataSource = _dataSource;
@synthesize delegate = _delegate;
@synthesize flipEnabled = _flipEnabled;
@synthesize currentView = _currentView;
@synthesize incomingView = _incomingView;
@synthesize numberOfPagesArray = _numberOfPagesArray;
@synthesize numberOfSections = _numberOfSections;
@synthesize currentSection = _currentSection;
@synthesize currentPage = _currentPage;
@synthesize animating = _animating;
@synthesize bgImageView = _bgImageView;

- (void)dealloc {
    self.dataSource = nil;
    self.delegate = nil;
    self.currentView = nil;
    self.incomingView = nil;
    self.numberOfPagesArray = nil;
    self.bgImageView = nil;
    
    [super dealloc];
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        
        //增加平移手势
		UIPanGestureRecognizer *panRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self 
                                                                                         action:@selector(panned:)] autorelease];
		[panRecognizer setMaximumNumberOfTouches:1];
        panRecognizer.delegate = self;
		[self addGestureRecognizer:panRecognizer];
        
        _flipEnabled = YES;
        _flipDirection = FlipViewDirectionNone;
        _currentPage = 0;
        _currentSection = 0;
        
    }
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

- (void)layoutSubviews {
    [super layoutSubviews];
    
//    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
//    
//    if (UIInterfaceOrientationIsPortrait(orientation)) { //竖屏
//        [self sendSubviewToBack:self.bgImageView];
//    } else { //横屏
//        [self sendSubviewToBack:self.bgImageView];
//    }
    [self sendSubviewToBack:self.bgImageView];
}

- (UIImageView *)bgImageView {
    if (!_bgImageView) {
        _bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 
                                                                     self.frame.size.width, self.frame.size.height)];
        _bgImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin;
        _bgImageView.backgroundColor = COLOR_RGB(246, 246, 246);
        [self addSubview:_bgImageView];
    }
    return _bgImageView;
}

- (void) cleanupFlip {
	
	_animating = NO;
    
	if (_setNewViewOnFlipDone) {
		[self.currentView removeFromSuperview];
		self.currentView = self.incomingView;
		self.incomingView = nil;
	} else {
		[self.incomingView removeFromSuperview];
		self.incomingView = nil;
	}
	
	_setNewViewOnFlipDone = NO;
    
    _flipDirection = FlipViewDirectionNone;
    
    //翻页结束响应事件
    if (self.delegate && [self.delegate respondsToSelector:@selector(flipView:flipDoneForPageInSectoin:atIndex:)]) {
        [self.delegate flipView:self flipDoneForPageInSectoin:_currentSection atIndex:_currentPage];
    }
    
}

- (BOOL)getBottomPage {
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(flipView:bottomPageInSectoin:)]) {
        self.incomingView = [self.dataSource flipView:self bottomPageInSectoin:self.currentSection];
    }
    if (self.incomingView) {
        _flipDirection = FlipViewDirectionLeft;
        _currentPage++;
        
        [self addSubview:self.incomingView];
        [self bringSubviewToFront:self.currentView];
        
        return YES;
    } else {
        return NO;
    }
}

- (BOOL)getPageAtIndex:(NSInteger)page{
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(flipView:pageInSectoin:atIndex:)]) {
        self.incomingView = [self.dataSource flipView:self pageInSectoin:_currentSection atIndex:page];
    }
    
    if (self.incomingView) {
        _flipDirection = page < _currentPage ? FlipViewDirectionRight : FlipViewDirectionLeft;
        _currentPage = page;
        
        
        [self addSubview:self.incomingView];
        
        if (_flipDirection == FlipViewDirectionLeft) {
            [self bringSubviewToFront:self.currentView];
            
            CGRect frame = self.incomingView.frame;
            frame.origin = CGPointZero;
            self.incomingView.frame = frame;
        }
        return YES;
    } else {
        return NO;
    }
}	

- (void)flipToSection:(NSInteger)section {
    [self flipToSection:section atIndex:0 animated:YES];
}

- (void)flipToSection:(NSInteger)section atIndex:(NSInteger)page animated:(BOOL)animated {
    if (section >= self.numberOfSections || section < 0) {
        return;
    }
    NSInteger numberOfPages = [(NSNumber *)[self.numberOfPagesArray objectAtIndex:section] integerValue];
    if (page >= numberOfPages || page < 0) {
        return;
    }
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(flipView:pageInSectoin:atIndex:)]) {
        self.incomingView = [self.dataSource flipView:self pageInSectoin:section atIndex:page];
    }
        
    if (self.incomingView) {
        if (section > _currentSection) {
            _flipDirection = FlipViewDirectionLeft;
        } else if (section < _currentSection) {
            _flipDirection = FlipViewDirectionRight;
        } else {
            if (page > _currentPage) {
                _flipDirection = FlipViewDirectionLeft;
            } else if (page < _currentPage) {
                _flipDirection = FlipViewDirectionRight;
            } else {
                _flipDirection = FlipViewDirectionNone;
            }
        }
        
        _currentSection = section;
        _currentPage = page;
        _setNewViewOnFlipDone = YES;
        
        [self addSubview:self.incomingView];
        BOOL userInteractionEnabled = self.userInteractionEnabled;
        
        if (animated && _flipDirection == FlipViewDirectionLeft) {
            [self bringSubviewToFront:self.currentView];
            CGRect frame = self.incomingView.frame;
            frame.origin = CGPointZero;
            self.incomingView.frame = frame;
            
            frame = self.currentView.frame;
            frame.origin.x = -frame.size.width;
            
            self.userInteractionEnabled = NO;
            [UIView animateWithDuration:kFlipAnimationIntervalMedium
                                  delay:0.0 options:UIViewAnimationCurveEaseInOut
                             animations:^{
                                 self.currentView.frame = frame;
                             }
                             completion:^(BOOL finished) {
                                 [self cleanupFlip];
                                 self.userInteractionEnabled = userInteractionEnabled;
                             }];
            
        } else if (animated && _flipDirection == FlipViewDirectionRight) {
            CGRect frame = self.incomingView.frame;
            frame.origin.x = -frame.size.width;
            self.incomingView.frame = frame;
            frame.origin.x = 0;
            self.userInteractionEnabled = NO;
            [UIView animateWithDuration:kFlipAnimationIntervalMedium
                                  delay:0.0 options:UIViewAnimationCurveEaseInOut
                             animations:^{
                                 self.incomingView.frame = frame;
                             }
                             completion:^(BOOL finished) {
                                 [self cleanupFlip];
                                 self.userInteractionEnabled = userInteractionEnabled;
                             }];
        } else {
            CGRect frame = self.incomingView.frame;
            frame.origin = CGPointZero;
            self.incomingView.frame = frame;
            
            if (!self.currentView || !self.currentView.superview) {
                [self cleanupFlip];
            } else {
                if (self.currentView == self.incomingView) {
                    _setNewViewOnFlipDone = NO;
                } else {
                
                    self.incomingView.hidden = YES;
                    self.incomingView.alpha = 0;
                    
                    [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationCurveEaseInOut
                                     animations:^{
                                         [self.incomingView setHidden:FALSE];	
                                         self.incomingView.alpha = 1;
                                     } 
                                     completion:^(BOOL finished) {
                                         [self cleanupFlip];
                                     }];
                }
            }
        }
    }
}

- (void)setFlipEnabled:(BOOL)flipEnabled {
    _flipEnabled = flipEnabled;
    
    for (UIGestureRecognizer *recognizer in self.gestureRecognizers) {
        recognizer.enabled = flipEnabled;
    }
}

- (void)setDataSource:(id<FlipViewDataSource>)dataSource {
	
	_dataSource = dataSource;
    
    if (_dataSource && [_dataSource respondsToSelector:@selector(numberOfSectionsInFlipView:)]) {
        self.numberOfSections = [_dataSource numberOfSectionsInFlipView:self];
        self.numberOfPagesArray = [NSMutableArray arrayWithCapacity:self.numberOfSections];
        if (self.numberOfSections > 0 && [_dataSource respondsToSelector:@selector(numberOfPagesInFlipView:inSection:)]) {
            for (int i = 0; i<self.numberOfSections; i++) {
                NSInteger number = [_dataSource numberOfPagesInFlipView:self inSection:i];
                [self.numberOfPagesArray addObject:[NSNumber numberWithInteger:number]];
            }
        }
    }
    
    self.currentSection = 0;
    self.currentPage = 0;
    
    [self flipToSection:self.currentSection];
}

- (void)reloadData {
    
    [self refreshData];
    
    if (self.currentSection > self.numberOfSections) {
        [self flipToSection:0];
    } else {
        NSInteger number = [(NSNumber *)[self.numberOfPagesArray objectAtIndex:self.currentSection] integerValue]-1;
        if (self.currentPage > number) {
            [self flipToSection:self.currentSection atIndex:number animated:YES];
        } else {
            [self flipToSection:self.currentSection atIndex:self.currentPage animated:YES];
        }
    }
}

- (void)refreshData {
    
    if (_dataSource && [_dataSource respondsToSelector:@selector(numberOfSectionsInFlipView:)]) {
        self.numberOfSections = [_dataSource numberOfSectionsInFlipView:self];
        self.numberOfPagesArray = [NSMutableArray arrayWithCapacity:self.numberOfSections];
        if (self.numberOfSections > 0 && [_dataSource respondsToSelector:@selector(numberOfPagesInFlipView:inSection:)]) {
            for (int i = 0; i<self.numberOfSections; i++) {
                NSInteger number = [_dataSource numberOfPagesInFlipView:self inSection:i];
                [self.numberOfPagesArray addObject:[NSNumber numberWithInteger:number]];
            }
        }
    }
}
#pragma mark -
#pragma mark FlipView Touch handler
- (void)panned:(UIPanGestureRecognizer *)recognizer {
    
    float translation = [recognizer translationInView:self].x;
    
    //若当前页为内容第一页，则禁用向右滑动效果
    if (translation >0 && _currentPage == 0 && !self.incomingView) 
        return;
    
    
    float progress = translation / self.bounds.size.width;
    
	static BOOL hasFailed;
	static BOOL initialized;
	
	static NSInteger oldPage;
    static NSInteger numberOfPages;
	
	switch (recognizer.state) {
		case UIGestureRecognizerStateBegan:
			if (!_animating) {
				hasFailed = NO;
				initialized = NO;
				_setNewViewOnFlipDone = NO;
			}
            
            numberOfPages = [(NSNumber *)[self.numberOfPagesArray objectAtIndex:self.currentSection] integerValue];
			break;
			
		case UIGestureRecognizerStateChanged:
			if (hasFailed) {
				return;
			}
            
			if (!initialized) {
				oldPage = self.currentPage;
				
				if (translation > 0) {
					if (self.currentPage > 0) {
						if (![self getPageAtIndex:self.currentPage - 1]) {
                            hasFailed = YES;
                            return;
                        }
					} else {
						hasFailed = YES;
						return;
					}
				} else {
                    NSInteger number = [(NSNumber *)[self.numberOfPagesArray objectAtIndex:self.currentSection] integerValue]-1;
                    if (self.currentPage < number) {
						if (![self getPageAtIndex:self.currentPage + 1]) {
                            hasFailed = YES;
                            return;
                        }
                    } else if (self.currentPage == number) {
                        if (![self getBottomPage]) {
                            hasFailed = YES;
                            return;
                        }
					} else {
						hasFailed = YES;
						return;
					}
				}
				
				hasFailed = NO;
				initialized = YES;
                _animating = YES;
				_setNewViewOnFlipDone = NO;
                
                if (_flipDirection == FlipViewDirectionRight) {
                    self.incomingView.layer.shadowColor=[UIColor blackColor].CGColor;
                    self.incomingView.layer.shadowOffset = CGSizeMake(4, 0);
                    self.incomingView.layer.shadowOpacity = 0.8;
                    self.incomingView.layer.shadowRadius = 3.0;
                    CGPathRef path = [UIBezierPath bezierPathWithRect:CGRectMake(self.incomingView.bounds.size.width-2,
                                                                                 0, 
                                                                                 2, 
                                                                                 self.incomingView.bounds.size.height)].CGPath;
                    [self.incomingView.layer setShadowPath:path];
                    
                } else if (_flipDirection == FlipViewDirectionLeft) {
                    self.currentView.layer.shadowColor=[UIColor blackColor].CGColor;
                    self.currentView.layer.shadowOffset = CGSizeMake(4, 0);
                    self.currentView.layer.shadowOpacity = 0.8;
                    self.currentView.layer.shadowRadius = 3.0;
                    CGPathRef path = [UIBezierPath bezierPathWithRect:CGRectMake(self.currentView.bounds.size.width-2,
                                                                                 0, 
                                                                                 2, 
                                                                                 self.currentView.bounds.size.height)].CGPath;
                    [self.currentView.layer setShadowPath:path];
                }
			}            
             
            CGFloat x;
            if (_flipDirection == FlipViewDirectionRight) {
                x = translation - self.incomingView.frame.size.width;
                
                if (x > 0) {
                    x = 0;
                }
                self.incomingView.frame = CGRectMake(x,
                                                     0,
                                                     self.incomingView.bounds.size.width,
                                                     self.incomingView.bounds.size.height);
            } else if (_flipDirection == FlipViewDirectionLeft) {
                x = translation;
                
                if (x > 0) {
                    x = 0;
                }
                self.currentView.frame = CGRectMake(x,
                                                    0,
                                                    self.currentView.bounds.size.width,
                                                    self.currentView.bounds.size.height);
            }
            
			break;
			
		case UIGestureRecognizerStateFailed:
        case UIGestureRecognizerStateCancelled:
		case UIGestureRecognizerStateRecognized:
			if (initialized) {
                //清除平移时添加的阴影效果
                self.currentView.layer.shadowOffset = CGSizeMake(0, 0);
                self.currentView.layer.shadowOpacity = 0;
                self.incomingView.layer.shadowOffset = CGSizeMake(0, 0);
                self.incomingView.layer.shadowOpacity = 0;
                
                CGFloat  originX;
                
                if (_currentPage == numberOfPages) {
                    _setNewViewOnFlipDone = NO;
                    _currentPage = oldPage;
                    originX = 0;
                    
                } else {
                    if ((fabs(progress)<kMoveThreshold)) {
                        _setNewViewOnFlipDone = NO;
                        _currentPage = oldPage;
                        originX = (_flipDirection==FlipViewDirectionRight)?-self.incomingView.frame.size.width:0;
                    }else{
                        _setNewViewOnFlipDone = YES;
                        originX = (_flipDirection==FlipViewDirectionLeft)?-self.currentView.frame.size.width:0;
                    }
                }
                if(_flipDirection == FlipViewDirectionRight){
                    CGRect rect = CGRectMake(originX,
                                             self.incomingView.frame.origin.y,
                                             self.incomingView.frame.size.width,
                                             self.incomingView.frame.size.height);
                    [UIView animateWithDuration:kFlipAnimationIntervalFast
                                     animations:^{
                                         [self.incomingView setFrame:rect];
                                     }
                                     completion:^(BOOL finished){
                                         [self cleanupFlip];
                                     }];
                }else if (_flipDirection == FlipViewDirectionLeft){
                    CGRect rect = CGRectMake(originX,
                                             self.currentView.frame.origin.y,
                                             self.currentView.frame.size.width,
                                             self.currentView.frame.size.height);
                    [UIView animateWithDuration:kFlipAnimationIntervalFast
                                     animations:^{
                                         [self.currentView setFrame:rect];
                                     }
                                     completion:^(BOOL finished){
                                         [self cleanupFlip];
                                     }];
                }
			}
			break;
        default:
            break;
            
	}
}


//-(void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
//    [self cleanupFlip];    
//}
//
//- (void)moveToSection:(NSInteger)section atIndex:(NSInteger)page inChannel:(BOOL)inChannel moveType:(FlipViewMoveType)moveType {
//    if (inChannel && page == _currentPage) {
//        return;
//    }
//    
//    if (self.dataSource && [self.dataSource respondsToSelector:@selector(flipView:pageInSectoin:atIndex:)]) {
//        self.incomingView = [self.dataSource flipView:self pageInSectoin:section atIndex:page];
//    }
//    
//    if (!self.incomingView) {
//        return;
//    }
//    
//    self.incomingView.hidden = YES;
//    
//    _currentPage = page;
//    _currentSection = section;
//    [self addSubview:self.incomingView];
//    
//    _setNewViewOnFlipDone = YES;
//    _animating = YES;    
//    
//    CATransition *transition = [CATransition animation];
//    transition.duration = kFlipAnimationIntervalFast;
//    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
//    transition.type = kCATransitionPush;
//    switch (moveType) {
//        case FlipViewMoveTypeFromLeftToRight:
//            transition.subtype = kCATransitionFromRight;
//            break;
//        case FlipViewMoveTypeFromRightToLeft:
//            transition.subtype = kCATransitionFromLeft;
//            break;
//        case FlipViewMoveTypeFromTopToBottom:
//            transition.subtype = kCATransitionFromBottom;
//            break;
//        case FlipViewMoveTypeFromBottomToTop:
//            transition.subtype = kCATransitionFromTop;
//            break;
//        default:
//            transition.subtype = kCATransitionFromRight;
//            break;
//    }
//    transition.delegate = self;
//    [self.layer addAnimation:transition forKey:nil];
//    self.incomingView.hidden = NO;
//    self.currentView.hidden = YES;
//}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]]) {
        UIScrollView *scrollView = (UIScrollView *)otherGestureRecognizer.view;
        if (scrollView.contentOffset.x <= 0) {
            return YES;
        }
    }
    return NO;
}
@end
